[小ネタ]ディレクトリ移動した際に自動で一時クレデンシャルを取得・設定する
こんにちは、AWS事業部の佐伯です。
同様の使い方をしてる方は多いかもしれませんが、今回はdirenvを使用してCLIでのAssumeRoleを簡単にする小ネタを書きたいと思います。
目的
権限の分離や請求情報の明確化のためAWSアカウントを分割している場合、全てのAWSアカウントにIAMユーザーを作成すると管理が煩雑になるため、IAMユーザーの管理はひとつのAWSアカウントにまとめ、その他のAWSアカウントへはスイッチロールで利用しているケースがあるかと思います。
しかし、各種CLIツールを使用するためには一時クレデンシャルをスイッチ先のAWSアカウントから取得し、環境変数に設定する必要があります。毎回AWS CLIを実行するのは面倒なので、今回はディレクトリ移動した際に自動で一時クレデンシャルを取得・設定し、楽をしようというのが目的です。
使用するツール
direnv
direnvは特定のディレクトリ移動した際に環境変数を設定してくれるツールです。
少し古いですがこちらの記事でも紹介されています。
remind101/assume-role
assume-roleはAWS CLIの設定ファイル(~/.aws/config)と認証情報ファイル(~/.aws/credentials)を読み込み、一時クレデンシャルを取得します。GitHubで検索すると同様のツールがいくつかありますが、私がこのツールを選んだ理由は以下のとおりです。
- 独自の設定ファイルを作成する必要がない(~/.aws/config, ~/.aws/credentialsはどちらもAWS CLIの設定ファイル、認証情報ファイル)
- 環境変数に設定するためのコマンドを標準出力することができる
設定
macOS(Sierra)、bashの環境で確認しています。その他OSやシェルを利用の場合は各ツールのREADME.mdをご確認ください。
direnvのインストールおよびセットアップ
Homebrewでdirenvをインストールし、~/.bashrcにフックの設定をします。
$ brew install direnv $ echo 'eval "$(direnv hook bash)"' >> ~/.bashrc $ exec $SHELL -l
remind101/assume-roleのインストール
Homebrewでremind101/assume-roleをインストールします。
$ brew install remind101/formulae/assume-role
AWS CLI設定
AWS CLIを使用してスイッチ元のAWSアカウントで作成したIAMユーザーのアクセスキーとシークレットアクセスキーを設定をします。
$ aws configure AWS Access Key ID [None]: AKIAIOEXAMPLEEXAMPLE AWS Secret Access Key [None]: wJalrXUtnFEXAMPLEKEYEXAMPLEKEYEXAMPLEKEY Default region name [None]: ap-northeast-1 #任意のリージョン Default output format [None]: json #任意のフォーマット
AWSアカウントIDおよびロール名を指定した、スイッチ先のAWSアカウントを名前付きプロファイルで設定します。
[default] region = ap-northeast-1 output = json [profile account-a] source_profile = default role_arn = arn:aws:iam::<AWSアカウントID>:role/<ロール名>
remind101/assume-roleはMFAが必須なロールでのAssumeRoleにも対応していますので、その場合は mfa_serial の設定も行います。こちらのエントリを参考にしてください。
プロファイル作成
ディレクトリに移動した際にdirenvがロードする.envrcファイルを作成します。
$ cd path/to/account-a $ echo 'eval $(assume-role $(basename $(pwd)))' >>.envrc
.envrcがカレントディレクトリに作成されるとエラーメッセージが出力されますので、direnv allow
で.envrcのロードを許可します。direnv allow
実行後、.envrcがロードされ各環境変数設定されます。
direnv: error .envrc is blocked. Run `direnv allow` to approve its content. $ direnv allow direnv: loading .envrc direnv: export +ASSUMED_ROLE +AWS_ACCESS_KEY_ID +AWS_SECRET_ACCESS_KEY +AWS_SECURITY_TOKEN +AWS_SESSION_TOKEN
.envrcの内容補足
assume-roleコマンドにカレントディレクトリを引数として渡しており、カレントディレクトリは名前付きプロファイルと同じ名前としているのでassume-role account-a
の実行結果をevalでコマンドとして実行し、環境変数に設定しています。
eval $(assume-role $(basename $(pwd)))
環境変数に設定しているだけなのでenv | grep AWS
などで取得した一時クレデンシャルの内容も確認できます。
$ env | grep AWS AWS_SESSION_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXX AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXX AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXXXXXXXXX AWS_SECURITY_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXX
一時クレデンシャルの有効期間
assume-roleで取得する一時クレデンシャルの有効期間はデフォルトで一時間です。有効期間切れとなった場合はdirenv reload
で再取得できます。
環境変数のアンロード
direnvで設定された環境変数は上位ディレクトリに移動するとアンロードされます。下位ディレクトリの場合は引き続き環境変数が有効となります。
$ cd .. direnv: unloading
まとめ
.envrcにはアクセスキーやシークレットアクセスキーを設定していないのでGitの管理対象にし、チームで運用されている場合も有効かと思います。
私自身のユースケースとしては、多くのAWSアカウントを触る機会があるので、各種ツール類のテンプレートと.envrcのテンプレートを保存した、プロジェクト用のテンプレートディレクトリを作成してコピーするといった運用をしています。